package com.minivision.migrate.service.impl;

import com.minivision.migrate.entity.DeviceApe;
import com.minivision.migrate.entity.DoorEvent;
import com.minivision.migrate.entity.HouseInfo;
import com.minivision.migrate.entity.Org;
import com.minivision.migrate.entity.PersonInfo;
import com.minivision.migrate.entity.VillageInfo;
import com.minivision.migrate.mapper.datacenter.DeviceApeMapper;
import com.minivision.migrate.mapper.datacenter.DoorEventMapper;
import com.minivision.migrate.mapper.datacenter.HouseInfoMapper;
import com.minivision.migrate.mapper.datacenter.PersonInfoMapper;
import com.minivision.migrate.mapper.datacenter.VillageInfoMapper;
import com.minivision.migrate.mapper.planet.OrgMapper;
import com.minivision.migrate.service.MigrateService;
import com.mongodb.BasicDBObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class MigrateServiceImpl implements MigrateService {

    @Autowired
    private OrgMapper orgMapper;

    @Autowired
    private VillageInfoMapper villageInfoMapper;

    @Autowired
    private HouseInfoMapper houseInfoMapper;

    @Autowired
    private PersonInfoMapper personInfoMapper;

    @Autowired
    private DoorEventMapper doorEventMapper;

    @Autowired
    private DeviceApeMapper deviceApeMapper;

    /**
     * MongoTemplate <br>
     */
    @Resource
    private MongoTemplate mongoTemplate;

    @Override
    public Integer migrateVillageAndHouse(int orgId) {
        log.info("导入小区信息数据开始");
        // 割接小区
        int villageId = migrateVillageInfo(orgId);
        log.info("导入小区信息数据结束");
        if (0 == villageId) {
            return 0;
        }

        log.info("导入小区楼栋房屋数据开始");
        // 割接房屋信息
        List<HouseInfo> houseList = querySubOrg(orgId);
        for (HouseInfo houseInfo : houseList) {
            // 必须是按照小区-楼栋-单元-房间结构
            // 如果没有楼栋信息，表示结构不完整，忽略
            if (StringUtils.isNotBlank(houseInfo.getLdxxbz())) {
                HouseInfo query = new HouseInfo();
                query.setPlanetOrgId(houseInfo.getPlanetOrgId());
                HouseInfo dbHouse = houseInfoMapper.selectOne(query);
                if (null == dbHouse) {
                    houseInfo.setXqxxbz(villageId);
                    houseInfoMapper.insertSelective(houseInfo);
                } else {
                    houseInfo.setXqxxbz(villageId);
                    houseInfo.setFwxxbz(dbHouse.getFwxxbz());
                    houseInfoMapper.updateByPrimaryKeySelective(houseInfo);
                }
            }
        }
        log.info("导入小区楼栋房屋数据结束");

        return villageId;
    }

    @Override
    public void migratePadRecord(int villageId) {
        if (0 == villageId) {
            return;
        }

        log.info("导入识别记录开始");
        Map<String, Integer> deviceMap = new HashMap<>();
        PersonInfo personQuery = new PersonInfo();
        personQuery.setXqxxbz(villageId);
        List<PersonInfo> infoList = personInfoMapper.select(personQuery);
        for (PersonInfo personInfo : infoList) {
            processSinglePerson(personInfo, deviceMap);

        }
        log.info("导入识别记录结束");
    }

    private void processSinglePerson(PersonInfo personInfo, Map<String, Integer> deviceMap) {
        int skip = 0;
        while (true) {
            Sort sort = new Sort(Sort.Direction.ASC, "_id");
            // 查询条件
            Criteria criteria = Criteria.where("personId").is(personInfo.getPlanetPersonId());
            Query query = new BasicQuery(criteria.getCriteriaObject());
            List<BasicDBObject> list = mongoTemplate.find(query.with(sort).skip(skip).limit(1000), BasicDBObject.class, "t_pad_record");
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            skip += list.size();

            for (BasicDBObject basicDBObject : list) {
                DoorEvent doorEventQuery = new DoorEvent();
                String recordId = basicDBObject.getString("_id");
                String deviceSn = basicDBObject.getString("deviceSn");
                doorEventQuery.setPlanetRecordId(recordId);
                DoorEvent dbInfo = doorEventMapper.selectOne(doorEventQuery);
                if (null == dbInfo) {
                    Integer datacenterDeviceId = getDatacenterDeviceId(deviceSn, deviceMap);
                    if (null != datacenterDeviceId) {
                        DoorEvent doorEvent = new DoorEvent();
                        doorEvent.setCjsbxxbz(datacenterDeviceId); //采集设备信息标识
                        doorEvent.setXqxxbz(personInfo.getXqxxbz()); // 小区信息标识
                        doorEvent.setFwxxbz(personInfo.getFwxxbz()); // 房屋信息标识
                        doorEvent.setRyxxbz(personInfo.getRyxxbz()); // 人员信息标识
//                        doorEvent.setKmsbbz(basicDBObject.getString("recognizeFlag")); //开门设别标识
                        doorEvent.setKmfsdm("09"); //开门方式代码,09-人脸
                        doorEvent.setCjsj(basicDBObject.getDate("createTime")); // 采集时间
                        doorEvent.setTp(basicDBObject.getString("snapUrl")); //开门照片
                        doorEvent.setSftgPdbz(basicDBObject.getString("recognizeFlag")); // 是否通过_判断标识,true通过
                        doorEvent.setXm(basicDBObject.getString("personName")); //姓名
                        doorEvent.setPlanetRecordId(recordId); // 记录标识
                        doorEventMapper.insertSelective(doorEvent);
                    }
                }
            }
        }
    }

    private Integer getDatacenterDeviceId(String deviceSn, Map<String, Integer> deviceMap) {
        if (deviceMap.containsKey(deviceSn)) {
            return deviceMap.get(deviceSn);
        } else {
            DeviceApe deviceApeQuery = new DeviceApe();
            deviceApeQuery.setPlanetDeviceSn(deviceSn);
            DeviceApe dbDeviceApe = deviceApeMapper.selectOne(deviceApeQuery);
            if (null != dbDeviceApe) {
                deviceMap.put(deviceSn, dbDeviceApe.getCjsbxxbz());
                return dbDeviceApe.getCjsbxxbz();
            }
            return null;
        }
    }

    @Override
    public List<Integer> getAllSubOrgIds(int orgId) {
        List<Integer> orgIds = new ArrayList<>();
        Org queryHouse = new Org();
        queryHouse.setParentId(orgId);
        List<Org> orgList = orgMapper.select(queryHouse);
        if (orgList.isEmpty()) {
            orgIds.add(orgId);
        } else {
            for (Org org : orgList) {
                List<Integer> subOrgIds = getAllSubOrgIds(org.getId());
                orgIds.addAll(subOrgIds);
            }
        }
        return orgIds;
    }

    private List<HouseInfo> querySubOrg(int orgId) {
        List<HouseInfo> houseList = new ArrayList<>();
        Org queryHouse = new Org();
        queryHouse.setParentId(orgId);
        List<Org> orgList = orgMapper.select(queryHouse);
        if (orgList.isEmpty()) {
            HouseInfo info = new HouseInfo();
            info.setPlanetOrgId(orgId);
            // 房间
            houseList.add(info);
        } else {
            // 楼栋
            for (Org org : orgList) {
                List<HouseInfo> subHouseList = querySubOrg(org.getId());
                fillHouseInfo(subHouseList, org);
                houseList.addAll(subHouseList);
            }
        }
        return houseList;
    }

    private void fillHouseInfo(List<HouseInfo> subHouseList, Org org) {
        String name = org.getName();
        for (HouseInfo info : subHouseList) {
            if (StringUtils.isBlank(info.getFjxxbz())) {
                info.setFjxxbz(name);

                if (null != org.getUpdateTime()) {
                    info.setGxsj(org.getUpdateTime());// 数据更新时间
                } else {
                    info.setGxsj(org.getCreateTime());// 数据更新时间
                }

            } else if (StringUtils.isBlank(info.getDyxxbz())) {
                info.setDyxxbz(name);
            } else if (StringUtils.isBlank(info.getLdxxbz())) {
                info.setLdxxbz(name);
            } else {
                info.setLdxxbz(name + info.getLdxxbz());
            }
        }
    }

    private int migrateVillageInfo(int orgId) {
        Org org = orgMapper.selectByPrimaryKey(orgId);
        if (null == org) {
            return 0;
        }

        VillageInfo info = new VillageInfo();
        info.setJlxxqmc(org.getName()); // 小区名称
        info.setHjdzXzqhdm(320114); // 行政区划代码

        if (null != org.getUpdateTime()) {
            info.setGxsj(org.getUpdateTime());// 数据更新时间
        } else {
            info.setGxsj(org.getCreateTime());// 数据更新时间
        }

        info.setXqlx(2); // 小区类型, 2-半封闭式
        info.setDzmc(org.getAddr()); // 地址名称
        info.setPlanetOrgId(orgId);

        VillageInfo query = new VillageInfo();
        query.setPlanetOrgId(orgId);
        VillageInfo dbInfo = villageInfoMapper.selectOne(query);
        if (null == dbInfo) {
            return villageInfoMapper.insertSelective(info);
        } else {
            info.setXqxxbz(dbInfo.getXqxxbz());
            villageInfoMapper.updateByPrimaryKeySelective(info);
            return dbInfo.getXqxxbz();
        }
    }
}
